<?php

namespace App\Admin\Repositories;

use App\Models\MemberTask as Model;
use Dcat\Admin\Repositories\EloquentRepository;
use Illuminate\Support\Facades\DB;

class MemberTask extends EloquentRepository
{
    /**
     * Model.
     *
     * @var string
     */
    protected $eloquentClass = Model::class;
    protected $memberMapModel = \App\Models\TaskMemberMap::class;

    public function getById($id)
    {
        $ret = $this->eloquentClass::query()->where('task_id', $id)->first();

        if ($ret) {
            return $ret->toArray();
        } else {
            return [];
        }
    }

    public function getTaskCountByDaysFromNow(int $days = 7, array $teamIds = []) : array
    {
        $query = $this->eloquentClass::query()
            ->select(DB::raw("DATE(created_at) AS days"), DB::raw("count(task_id) AS num"))
            ->where(DB::raw("DATE_SUB(CURDATE(), INTERVAL {$days} DAY)"), "<=", DB::raw("DATE(created_at)"));
        if(!empty($teamIds)){
            $query->whereIn('team_id', $teamIds);
        }

        return $query->groupBy('days')
        ->orderBy('days')
        ->get()
        ->toArray();
    }

    public function getTaskCountByDays(int $days = 7, array $teamIds = []) : int
    {
        $query = $this->eloquentClass::query()
            ->select('task_id');
        if(!empty($teamIds)){
            $query->whereIn('team_id', $teamIds);
        }

        $cnt = $query->where(DB::raw("DATE_SUB(CURDATE(), INTERVAL {$days} DAY)"), "<=", DB::raw("DATE(created_at)"))->count();
        return (int) $cnt;
    }

    public function getTaskCountByStatus(int $memberId) : array
    {
        $list = $this->eloquentClass::query()
            ->select('status', DB::Raw('count(DISTINCT(member_task.task_id)) cnt'))
            ->leftjoin('task_member_map', 'task_member_map.task_id', '=', 'member_task.task_id')
            ->where('member_id', $memberId)
            ->groupBy('status')
            ->get()
            ->toArray();
        return $list;
    }

    public function getTaskCountByProgress(array $teamIds = []) : array
    {
        $query = $this->eloquentClass::query()
            ->select('progress', DB::Raw('COUNT(task_id) AS cnt'))
            ->where('status', '!=', \App\Models\MemberTask::TASK_STATUS_COMPLETE);
        if (!empty($teamIds)){
            $query->whereIn('team_id', $teamIds);
        }
        return $query->groupBy('progress')->get()->keyBy('progress')->toArray();
    }

    public function getTaskCountByStatusUseTeamIds(Array $teamIds = []) : array
    {
        $list = $this->eloquentClass::query()
            ->select('status', DB::Raw('count(DISTINCT(member_task.task_id)) cnt'))
            ->leftjoin('task_member_map', 'task_member_map.task_id', '=', 'member_task.task_id');
        if (!empty($teamIds)){
            $list = $list->whereIn('team_id', $teamIds);
        }
        $list = $list->groupBy('status')
            ->get()
            ->keyBy('status')
            ->toArray();
        return $list;
    }

    public function getTaskCountByMemberIdAndProgress(int $memberId, int $progress) : int
    {
        $cnt = $this->eloquentClass::query()
            ->leftjoin('task_member_map', 'task_member_map.task_id', '=', 'member_task.task_id')
            ->where('task_member_map.member_id', $memberId)
            ->where('progress', $progress)
            ->count();
        return (int) $cnt;
    }

    public function getCurrentCompleteTaskCount(int $memberId, int $currentDays = 7) : int
    {
        $cnt = $this->eloquentClass::query()
            ->leftjoin('task_member_map', 'task_member_map.task_id', '=', 'member_task.task_id')
            ->where('task_member_map.member_id', $memberId)
            ->where('member_task.status', \App\Models\MemberTask::TASK_STATUS_COMPLETE)
            ->where(DB::raw("DATE_SUB(CURDATE(), INTERVAL {$currentDays} DAY)"), "<=", DB::raw("DATE(completed_at)"))
            ->count();
        return (int) $cnt;
    }

    public function add(
        int $departmentId,
        int $teamId,
        string $taskName,
        string $projectName,
        string $startTime,
        string $endTime,
        int $priority,
        array $memberList,
        string $taskDesc = NULL,
        int $status = \App\Models\MemberTask::TASK_STATUS_ING,
        int $progress = \App\Models\MemberTask::TASK_PROGRESS_NORMAL,
        string $completedAt = null)
    {
        DB::beginTransaction();
        $id = $this->eloquentClass::query()->insertGetId([
            'department_id' => $departmentId,
            'team_id' => $teamId,
            'task_name' => $taskName,
            'project_name' => $projectName,
            'start_time' => $startTime,
            'end_time' => $endTime,
            'task_desc' => $taskDesc,
            'priority' => $priority,
            'status' => $status,
            'progress' => $progress,
            'completed_at' => $completedAt,
        ]);
        if ($id) {
            $data = [];
            foreach ($memberList as $uid){
                if (!empty($uid))
                    $data[] = ['task_id' => $id, 'member_id' => $uid];
            }
            if ($this->memberMapModel::query()->insert($data)){
                DB::commit();
                return $id;
            }
        }
        DB::rollBack();
        return false;
    }

    public function updateFields(int $taskId, array $data) : bool
    {
        return $this->eloquentClass::query()
            ->where('task_id', $taskId)
            ->update($data);
    }

    public function updt(
        int $taskId,
        int $departmentId,
        int $teamId,
        string $taskName,
        string $projectName,
        string $startTime,
        string $endTime,
        int $priority,
        array $memberList,
        string $taskDesc = NULL,
        int $status = \App\Models\MemberTask::TASK_STATUS_ING,
        int $progress = \App\Models\MemberTask::TASK_PROGRESS_NORMAL,
        string $completedAt = null) : bool
    {
        DB::beginTransaction();
        $id = $this->eloquentClass::query()
            ->where('task_id', $taskId)
            ->update([
                'department_id' => $departmentId,
                'team_id' => $teamId,
                'task_name' => $taskName,
                'project_name' => $projectName,
                'task_desc' => $taskDesc,
                'start_time' => $startTime,
                'end_time' => $endTime,
                'priority' => $priority,
                'status' => $status,
                'progress' => $progress,
                'completed_at' => $completedAt,
            ]);

        $this->memberMapModel::query()->where('task_id', $taskId)->delete();

        if ($id) {
            $data = [];
            foreach ($memberList as $uid){
                if (!empty($uid))
                    $data[] = ['task_id' => $taskId, 'member_id' => $uid];
            }
            if ($this->memberMapModel::query()->insert($data)){
                DB::commit();
                return true;
            }
        }
        DB::rollBack();
        return false;
    }

    public function del(int $id) : bool
    {
        DB::beginTransaction();
        if (
            $this->eloquentClass::query()->where('task_id', $id)->delete() &&
            $this->memberMapModel::query()->where('task_id', $id)->delete()
        ){
            DB::commit();
            return true;
        }
        DB::rollBack();
        return false;
    }
}
